#!/bin/bash

# 定义颜色变量
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m' # 重置颜色

# 定义操作提示函数
function print_info() {
    echo -e "${YELLOW}$1${NC}"
}

# 定义错误提示函数
function print_error() {
    echo -e "${RED}$1${NC}"
}


# 配置 Docker 镜像源的函数
function configure_docker_mirror() {
    new_config=$(cat << EOF
{
    "registry-mirrors": [
        "https://docker.m.daocloud.io",
        "https://noohub.ru",
        "https://huecker.io",
        "https://dockerhub.timeweb.cloud",
        "https://0c105db5188026850f80c001def654a0.mirror.swr.myhuaweicloud.com",
        "https://5tqw56kt.mirror.aliyuncs.com",
        "https://docker.1panel.live",
        "http://mirrors.ustc.edu.cn/",
        "http://mirror.azure.cn/",
        "https://hub.rat.dev/",
        "https://docker.ckyl.me/",
        "https://docker.chenby.cn",
        "https://docker.hpcloud.cloud",
        "https://docker.m.daocloud.io"
    ]
}
EOF
    )

    # 检查 /etc/docker/daemon.json 文件是否存在
    if [ -f /etc/docker/daemon.json ]; then
        # 获取当前日期时间，格式为 YYYYMMDDHHMMSS
        current_datetime=$(date +"%Y%m%d%H%M%S")
        # 备份当前配置，文件名加上日期时间
        \cp /etc/docker/daemon.json /etc/docker/daemon.json.${current_datetime}.bak
        # 读取当前配置
        current_config=$(cat /etc/docker/daemon.json)
        # 比较配置内容
        if [ "$current_config" = "$new_config" ]; then
            print_info "Docker 镜像源配置已符合要求，无需重新设置和重启 Docker 服务。"
        else
            print_info "开始设置 Docker 镜像源..."
            echo "$new_config" > /etc/docker/daemon.json
            if [ $? -eq 0 ]; then
                print_info "Docker 镜像源设置完成。"
            else
                print_error "Docker 镜像源设置失败！"
                exit 1
            fi

            # 重启 docker 服务
            print_info "开始重启 Docker 服务..."
            systemctl restart docker
            if [ $? -eq 0 ]; then
                print_info "Docker 服务重启完成, 等待5秒..."
                sleep 5
            else
                print_error "Docker 服务重启失败！"
                exit 1
            fi
        fi
    else
        print_info "开始设置 Docker 镜像源..."
        echo "$new_config" > /etc/docker/daemon.json
        if [ $? -eq 0 ]; then
            print_info "Docker 镜像源设置完成。"
        else
            print_error "Docker 镜像源设置失败！"
            exit 1
        fi

        # 重启 docker 服务
        print_info "开始重启 Docker 服务..."
        systemctl restart docker
        if [ $? -eq 0 ]; then
            print_info "Docker 服务重启完成, 等待5秒..."
            sleep 5
        else
            print_error "Docker 服务重启失败！"
            exit 1
        fi
    fi
}

# 提示用户是否配置 Docker 镜像源加速
read -p "是否需要配置 Docker 镜像源加速？(y/n): " choice
if [ "$choice" == "y" ] || [ "$choice" == "Y" ]; then
    configure_docker_mirror
else
    print_info "已选择不配置 Docker 镜像源加速。"
fi



# 初始化标志变量
emqx_pulled=false
postgres_pulled=false

# 检查 emqx/emqx:5.8.5 镜像是否存在
emqx_image_count=$(docker images | grep -E "emqx/emqx[[:space:]]+5.8.5" | wc -l)
if [ "$emqx_image_count" -ge 1 ]; then
    print_info "emqx/emqx:5.8.5 镜像已存在，无需拉取。"
else
    print_info "开始在后台拉取 emqx/emqx:5.8.5 镜像..."
    print_info "开始执行 nohup docker pull emqx/emqx:5.8.5 > emqx_pull.log 2>&1 &"
    nohup docker pull emqx/emqx:5.8.5 > emqx_pull.log 2>&1 &
    emqx_pid=$!
    print_info "emqx/emqx:5.8.5 镜像拉取进程 ID: $emqx_pid"
    emqx_pulled=true
fi

# 检查 postgres:16-alpine 镜像是否存在
postgres_image_count=$(docker images | grep -E "postgres[[:space:]]+16-alpine" | wc -l)
if [ "$postgres_image_count" -ge 1 ]; then
    print_info "postgres:16-alpine 镜像已存在，无需拉取。"
else
    print_info "开始在后台拉取 postgres:16-alpine 镜像..."
    print_info "开始执行 nohup docker pull postgres:16-alpine > postgres_pull.log 2>&1 &"
    nohup docker pull postgres:16-alpine > postgres_pull.log 2>&1 &
    postgres_pid=$!
    print_info "postgres:16-alpine 镜像拉取进程 ID: $postgres_pid"
    postgres_pulled=true
fi

# 构建镜像
print_info "开始构建 backend 镜像..."
cd backend && docker build -t backend .
if [ $? -eq 0 ]; then
    print_info "backend 镜像构建完成。"
else
    print_error "backend 镜像构建失败！"
    exit 1
fi
cd ..

print_info "开始构建 frontend 镜像..."
cd frontend && docker build -t frontend .
if [ $? -eq 0 ]; then
    print_info "frontend 镜像构建完成。"
else
    print_error "frontend 镜像构建失败！"
    exit 1
fi
cd ..



# 等待 emqx 拉取进程完成（如果执行了拉取操作）
print_info "等待后台拉取emqx以及postgres镜像..."
if $emqx_pulled; then
    wait $emqx_pid
    if [ $? -eq 0 ]; then
        print_info "emqx/emqx:5.8.5 镜像拉取完成。"
    else
        print_error "emqx/emqx:5.8.5 镜像拉取失败！请查看 emqx_pull.log"
        exit 1
    fi
else
    print_info "emqx/emqx:5.8.5 镜像已拉取。"
fi

# 等待 postgres 拉取进程完成（如果执行了拉取操作）
if $postgres_pulled; then
    wait $postgres_pid
    if [ $? -eq 0 ]; then
        print_info "postgres:16-alpine 镜像拉取完成。"
    else
        print_error "postgres:16-alpine 镜像拉取失败！请查看 postgres_pull.log"
        exit 1
    fi
else
    print_info "postgres:16-alpine 镜像已拉取。"
fi


print_info "检查 backend/frontend/emqx/postgres 镜像是否全部已构建完成"
image_count=$(docker images | grep -E "backend|frontend|postgres|emqx" | wc -l)
if [ "$image_count" -ge 4 ]; then
    print_info "镜像已成功构建。"
else
    print_error "镜像构建失败！"
    exit 1
fi


# 构建子网及目录

# 生成 0 - 255 之间的随机整数
random_num=$(shuf -i 2-254 -n 1)
# 构建随机子网
subnet="192.168.${random_num}.0/24"
# 检查 cloud_sms 网络是否已存在
network_count=$(docker network ls | grep cloud_sms | wc -l)
if [ "$network_count" -eq 1 ]; then
    print_info "Docker 网络 cloud_sms 已存在，无需重复创建。"
else
    print_info "开始创建 Docker 网络，子网为 ${subnet}..."
    docker network create cloud_sms --subnet "$subnet"
    network_count=$(docker network ls | grep cloud_sms | wc -l)
    if [ "$network_count" -eq 1 ]; then
        print_info "Docker 网络创建完成，子网为 ${subnet}。"
    else
        print_error "Docker 网络创建失败！"
        exit 1
    fi
fi

print_info "开始创建配件目录..."
mkdir -p {log,conf,data}/{backend,postgres-db,emqx,frontend}
if [ $? -eq 0 ]; then
    print_info "配件目录创建完成。"
else
    print_error "配件目录创建失败！"
    exit 1
fi

print_info "开始修改 emqx 目录权限..."
chown -R 1000:1000 log/emqx data/emqx
if [ $? -eq 0 ]; then
    print_info "emqx 目录权限修改完成。"
else
    print_error "emqx 目录权限修改失败！"
    exit 1
fi

# 构建配置
print_info "开始复制 backend 配置文件..."
cp backend/conf.ini conf/backend/
if [ $? -eq 0 ]; then
    print_info "backend 配置文件复制完成。"
else
    print_error "backend 配置文件复制失败！"
    exit 1
fi

print_info "开始复制 backend 许可证文件..."
cp backend/license conf/backend/
if [ $? -eq 0 ]; then
    print_info "backend 许可证文件复制完成。"
else
    print_error "backend 许可证文件复制失败！"
    exit 1
fi

print_info "开始复制 frontend 配置文件..."
cp -r frontend/nginx_conf/* conf/frontend/
if [ $? -eq 0 ]; then
    print_info "frontend 配置文件复制完成。"
else
    print_error "frontend 配置文件复制失败！"
    exit 1
fi



# 第一次运行时运行服务
print_info "开始启动数据库服务..."
docker-compose up -d postgres-db
if [ $? -eq 0 ]; then
    print_info "数据库服务启动完成。"
else
    print_error "数据库服务启动失败！"
    exit 1
fi

print_info "开始启动 emqx 服务..."
docker-compose up -d emqx
if [ $? -eq 0 ]; then
    print_info "emqx 服务启动完成。"
else
    print_error "emqx 服务启动失败！"
    exit 1
fi

# 获取机器的IP地址
ip_address=$(hostname -I | awk '{print $1}')
print_info "请访问服务器 ${ip_address}:18083 访问 emqx web 界面，例如 http://${ip_address}:18083"
print_info "访问页面后输入 admin, public 登录，提示需要更改密码，请根据提示修改"
print_info "点击左侧菜单栏的访问控制->客户端认证->创建->Password-Based->内置数据库->创建->用户管理->点击 + 号(新建用户)->输入指定的用户名 cloud_sms 与密码 @cloud#sms，并勾选为超级用户创建"
read -p "完成上述 emqx 配置后，按回车键继续..."
read -p "确认操作完成?, 请按回车键继续..."

print_info "开始启动后端服务..."
docker-compose up -d backend
if [ $? -eq 0 ]; then
    print_info "后端服务启动完成。"
else
    print_error "后端服务启动失败！"
    exit 1
fi

print_info "开始启动前端服务..."
docker-compose up -d frontend
if [ $? -eq 0 ]; then
    print_info "前端服务启动完成。"
else
    print_error "前端服务启动失败！"
    exit 1
fi
print_info "等待10秒..."
sleep 10
# 许可证放置
print_info "检查后端服务许可证状态..."
license_check_count=$(docker logs backend 2>&1 | head -n 50 | grep "许可证验证通过" | wc -l)
if [ "$license_check_count" -ge 1 ]; then
    print_info "后端服务许可证验证通过，无需处理。"
else
    device_id=$(docker logs backend 2>&1 | head -n 50 | grep "设备id" | awk -F "INFO-" '{print $2}')
    print_info "检测到设备还未授权: $device_id"
    print_info "请将该设备 ID 发给管理员，获取 license 文件。"
    # 获取当前路径
    current_path=$(pwd)
    read -p "请新开一个终端，执行 cd ${current_path}/conf/backend/ ，将获取到的新的 license 文件替换该路径下的 license 文件后，按回车键继续..."
    read -p "确认替换完成?, 请按回车键继续..."
    print_info "开始重启 后端/前端 服务以应用新许可证..."
    docker restart backend frontend
    if [ $? -eq 0 ]; then
        print_info "后端/前端 服务重启完成，等待5秒"
        sleep 5
        license_check_count=$(docker logs backend 2>&1 | grep "许可证验证通过" | wc -l)
        if [ "$license_check_count" -ge 1 ]; then
            print_info "后端服务许可证验证通过"
        else
            print_error "后端服务许可证验证仍未通过，请检查 license 文件！"
            exit 1
        fi
    else
        print_error "后端服务重启失败！"
        exit 1
    fi
fi


# 提示后期维护命令
echo ""
print_info "部署完成!"

content=$(cat << "EOF"
    __         ____              __                __
   / /_  ___  / / /___     _____/ /___  __  ______/ /     _________ ___  _____
  / __ \/ _ \/ / / __ \   / ___/ / __ \/ / / / __  /_____/ ___/ __ `__ \/ ___/
 / / / /  __/ / / /_/ /  / /__/ / /_/ / /_/ / /_/ /_____(__  ) / / / / (__  )
/_/ /_/\___/_/_/\____/   \___/_/\____/\__,_/\__,_/     /____/_/ /_/ /_/____/
EOF
)
echo "$content"
echo ""
print_info "服务访问地址: https://${ip_address}"
print_info "默认管理员账密 admin/__GK__"
print_info "若浏览器提示 '您的连接不是私密连接', 请点击'高级','继续前往${ip_address}'"


echo ""
echo ""
print_info "维护命令:"
print_info "关闭所有服务:  docker-compose down"
print_info "启动所有服务:  docker-compose up -d"
print_info "查看日志:     docker-compose logs -f"
print_info "修改配置后更新单个服务:  docker-compose stop 服务名 && docker-compose rm -f 服务名 && docker-compose up -d 服务名"
print_info "示例: 重建backend服务"
print_info "docker-compose stop backend && docker-compose rm -f backend && docker-compose up -d backend"
echo ""
echo ""
print_info "更新计划:"
print_info "3月份支持AT固件, 届时, 不仅银尔达的设备, 所有的物联网设备, 只要能够支持MQTT协议, 都能接入平台,正在开发中.."
print_info "4月份支持生成匿名链接, 支持设置连接有效期, 可分享设备,他人可通过匿名链接访问设备, 正在开发中.."
print_info "AT固件电话功能..敬请期待"

# emq服务重建后会丢失数据, 请排查是否有id为1000的用户, 将其删除即可, 排查命令如下
# cat /etc/passwd|grep 1000  若有输出, 则执行userdel -r 用户名   删除该用户